{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Numpy\n",
    "\n",
    "NumPy（Numerical Python）是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵，比Python自身的嵌套列表（nested list structure)结构要高效的多（该结构也可以用来表示矩阵**matrix**），支持大量的维度数组与矩阵运算，此外也针对数组运算提供大量的数学函数库. \n",
    "\n",
    "NumPy（Numeric Python）提供了许多高级的数值编程工具，如：**矩阵数据类型**、**矢量处理**，以及精密的运算库。专为进行严格的数字处理而产生。多为很多**大型金融公司**使用，以及核心的科学计算组织如：Lawrence Livermore，NASA用其处理一些本来使用C++，Fortran或Matlab等所做的任务。\n",
    "\n",
    "NumPy 的前身为 Numeric，最早由 Jim Hugunin 与其它协作者共同开发，2005 年，Travis Oliphant 在 Numeric 中结合了另一个同性质的程序库 Numarray 的特色，并加入了其它扩展而开发了 NumPy。NumPy 为开放源代码并且由许多协作者共同维护开发。\n",
    "\n",
    "#### Numpy 教程\n",
    "\n",
    "- 官方教程 （英文） https://numpy.org/doc/stable/user/quickstart.html\n",
    "- Numpy中文网  https://www.numpy.org.cn/\n",
    "- Numpy 菜鸟教程 https://www.runoob.com/numpy/numpy-tutorial.html\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'1.20.1'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np   # 导入numpy模块\n",
    "np.__version__"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Numpy的数据结构\n",
    "\n",
    "NumPy 数组的维数称为秩（rank），秩就是轴的数量，即数组的维度，一维数组的秩为 1，二维数组的秩为 2，以此类推。\n",
    "\n",
    "在 NumPy中，每一个线性的数组称为是一个轴（axis），也就是维度（dimensions）。比如说，二维数组相当于是两个一维数组，其中第一个一维数组中每个元素又是一个一维数组。所以一维数组就是 NumPy 中的轴（axis），第一个轴相当于是底层数组，第二个轴是底层数组里的数组。而轴的数量 — 秩，就是数组的维数。\n",
    "\n",
    "很多时候可以声明 axis。axis=0，表示沿着第 0 轴进行操作，即对每一列进行操作；axis=1，表示沿着第1轴进行操作，即对每一行进行操作。\n",
    "\n",
    "NumPy 的数组中比较重要 ndarray 对象属性有：\n",
    "\n",
    "- ndarray.ndim \t  秩，即轴的数量或维度的数量\n",
    "- ndarray.shape   数组的维度，对于矩阵，n 行 m 列\n",
    "- ndarray.size \t  数组元素的总个数，相当于 .shape 中 n*m 的值\n",
    "- ndarray.dtype   ndarray 对象的元素类型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.67497884 0.74365826 0.11049645 0.34200921 0.83730297 0.16112518\n",
      " 0.64456253 0.01897481 0.34397336 0.44400478 0.86530451 0.76648118\n",
      " 0.79855579 0.52605236 0.17774474 0.57357227 0.47322626 0.08847508\n",
      " 0.00541124 0.96392024 0.84684207 0.70142698 0.30215742 0.15778681\n",
      " 0.14291563 0.18002984 0.47177526 0.16025584 0.15736658 0.17790203\n",
      " 0.31703224 0.48100671 0.15708195 0.75356239 0.06672335 0.75341732\n",
      " 0.84414594 0.18550314 0.25076828 0.46369581 0.21461733 0.63562547\n",
      " 0.21568787 0.10165615 0.4766322  0.11563854 0.29620995 0.30480358\n",
      " 0.23125344 0.62126829]\n"
     ]
    }
   ],
   "source": [
    "stock_return = np.random.random(50)  # 假设有5个股票，各4天的收益率是20个随机数  np.random.random 用以产生随机数\n",
    "print(stock_return)\n",
    "#type(stock_return)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.67497884 0.74365826 0.11049645 0.34200921 0.83730297]\n",
      " [0.16112518 0.64456253 0.01897481 0.34397336 0.44400478]\n",
      " [0.86530451 0.76648118 0.79855579 0.52605236 0.17774474]\n",
      " [0.57357227 0.47322626 0.08847508 0.00541124 0.96392024]\n",
      " [0.84684207 0.70142698 0.30215742 0.15778681 0.14291563]\n",
      " [0.18002984 0.47177526 0.16025584 0.15736658 0.17790203]\n",
      " [0.31703224 0.48100671 0.15708195 0.75356239 0.06672335]\n",
      " [0.75341732 0.84414594 0.18550314 0.25076828 0.46369581]\n",
      " [0.21461733 0.63562547 0.21568787 0.10165615 0.4766322 ]\n",
      " [0.11563854 0.29620995 0.30480358 0.23125344 0.62126829]]\n",
      "stock_return的维度是：\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "# 将数据调整成 4 * 5 的维度\n",
    "stock_return = stock_return.reshape(10,5)\n",
    "print(stock_return)\n",
    "print('stock_return的维度是：')\n",
    "print(stock_return.ndim)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(4, 5)"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stock_return.shape  # 查看其维度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "20"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stock_return.size # 查看其大小"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 创建数组\n",
    "\n",
    "- 创建全零或者全1的数组\n",
    "- 创建一个index序列，通常在循环中需要使用\n",
    "- 创建等差数列、等比数列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 1]\n",
      " [1 1]\n",
      " [1 1]]\n"
     ]
    }
   ],
   "source": [
    "# 生成全零或者全一矩阵\n",
    "zeros = np.zeros(5)\n",
    "ones = np.ones((3,2), dtype = int)\n",
    "print(ones)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 2, 3, 4, 5])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将列表转成 array\n",
    "ones = [1,2,3,4,5]\n",
    "new_ones = np.asarray(ones)\n",
    "\n",
    "new_ones"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[10 12 14 16 18]\n",
      "[0, 1, 2, 3, 4]\n",
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n",
      "7\n",
      "8\n",
      "9\n"
     ]
    }
   ],
   "source": [
    "x = np.arange(10,20,2)  \n",
    "print (x)\n",
    "\n",
    "x_list = [y for y in range(5)]\n",
    "print(x_list)\n",
    "\n",
    "for i in range(10):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 5  6  8 10 11 13 15 16 18 20]\n"
     ]
    }
   ],
   "source": [
    "# np.linspace(start, stop, num=50, dtype)\n",
    "x = np.linspace(5, 20, num = 10, dtype = int)  \n",
    "print (x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[  8  16  32  64 128 256 512]\n"
     ]
    }
   ],
   "source": [
    "# np.logspace 函数用于创建一个于等比数列, base 参数意思是取对数的时候 log 的下标\n",
    "# np.logspace(start, stop, num=50, base=10.0, dtype=None)\n",
    "x = np.logspace(0,9,10,base=2, dtype = int)\n",
    "n =5\n",
    "print (x[x>5])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 数组的索引、切片和排序\n",
    "\n",
    "- **索引和切片**\n",
    "ndarray 数组可以基于 0 - n 的下标进行索引， 通常可以通过冒号分隔切片参数 start:stop:step 来进行切片操作\n",
    "\n",
    ">冒号的解释：如果只放置一个参数，如 [2]，将返回与该索引相对应的单个元素。如果为 [2:]，表示从该索引开始以后的所有项都将被提取。如果使用了两个参数，如 [2:7]，那么则提取两个索引(不包括停止索引)之间的项。\n",
    "\n",
    ">布尔索引：布尔索引通过布尔运算（如：比较运算符）来获取符合指定条件的元素的数组\n",
    "\n",
    "- **排序**\n",
    "NumPy 提供了多种排序的方法。 这些排序函数实现不同的排序算法\n",
    "\n",
    ">numpy.sort() 函数返回输入数组的排序副本\n",
    "\n",
    ">numpy.argsort() 函数返回的是数组值从小到大的索引值\n",
    "\n",
    ">numpy.argmax() 和 numpy.argmin()函数分别沿给定轴返回最大和最小元素的索引\n",
    "\n",
    ">numpy.where() 函数返回输入数组中满足给定条件的元素的索引\n",
    "\n",
    ">numpy.extract() 函数根据某个条件从数组中抽取元素，返回满条件的元素。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 3 4 5 6 7]\n"
     ]
    }
   ],
   "source": [
    "# 索引和切片\n",
    "a = np.arange(10)  \n",
    "b = a[2:7:2]   # 从索引 2 开始到索引 7 停止，间隔为 2\n",
    "c = a[3:] # 从索引 3 开始到结束\n",
    "d = a[:-2]  # 从索引 0 开始到倒数第 2\n",
    "print(d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "大于 5 的元素是：\n",
      "[ 6  7  8  9 10 11]\n"
     ]
    }
   ],
   "source": [
    "# 索引和切片\n",
    "x = np.array([[  0,  1,  2],[  3,  4,  5],[  6,  7,  8],[  9,  10,  11]])  \n",
    "# 现在我们会打印出大于 5 的元素  \n",
    "print  ('大于 5 的元素是：')\n",
    "print (x[x >  5])  # 布尔索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "原始数组是：\n",
      "[[3 7]\n",
      " [9 1]]\n",
      "\n",
      "\n",
      "按行排序：\n",
      "[[3 7]\n",
      " [1 9]]\n",
      "\n",
      "\n",
      "按列排序：\n",
      "[[3 7]\n",
      " [1 9]]\n"
     ]
    }
   ],
   "source": [
    "# 排序 np.sort\n",
    "x = np.array([[3,7],[9,1]])  \n",
    "print ('原始数组是：')\n",
    "print (x)\n",
    "print ('\\n')\n",
    "print ('按行排序：')\n",
    "print (np.sort(x, axis = 1))\n",
    "print ('\\n')\n",
    "print ('按列排序：')\n",
    "print (np.sort(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "原始数组是：\n",
      "[3 1 2]\n",
      "\n",
      "\n",
      "对 x 调用 argsort() 函数：\n",
      "[1 2 0]\n",
      "\n",
      "\n",
      "以排序后的顺序重构原数组：\n",
      "[1 2 3]\n"
     ]
    }
   ],
   "source": [
    "# 排序 np.argsort\n",
    "\n",
    "x = np.array([3,  1,  2])  \n",
    "print ('原始数组是：')\n",
    "print (x)\n",
    "print ('\\n')\n",
    "print ('对 x 调用 argsort() 函数：')\n",
    "y = np.argsort(x)  \n",
    "print (y)\n",
    "print ('\\n')\n",
    "print ('以排序后的顺序重构原数组：')\n",
    "print (x[y])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "原始数组是：\n",
      "[[30 40 70]\n",
      " [80 20 10]\n",
      " [50 90 60]]\n",
      "\n",
      "\n",
      "调用 argmax() 函数：\n",
      "7\n",
      "\n",
      "\n",
      "展开数组：\n",
      "[30 40 70 80 20 10 50 90 60]\n",
      "\n",
      "\n",
      "沿轴 0 的最大值索引：\n",
      "[1 2 0]\n",
      "\n",
      "\n",
      "沿轴 1 的最大值索引：\n",
      "[2 0 1]\n",
      "\n",
      "\n",
      "调用 argmin() 函数：\n",
      "5\n",
      "\n",
      "\n",
      "展开数组中的最小值：\n",
      "10\n",
      "\n",
      "\n",
      "沿轴 0 的最小值索引：\n",
      "[0 1 1]\n",
      "\n",
      "\n",
      "沿轴 1 的最小值索引：\n",
      "[0 2 0]\n"
     ]
    }
   ],
   "source": [
    "#  numpy.argmax() 和 numpy.argmin()\n",
    "x = np.array([[30,40,70],[80,20,10],[50,90,60]])  \n",
    "print  ('原始数组是：') \n",
    "print (x) \n",
    "print ('\\n') \n",
    "print ('调用 argmax() 函数：') \n",
    "print (np.argmax(x)) \n",
    "print ('\\n') \n",
    "print ('展开数组：') \n",
    "print (x.flatten()) \n",
    "print ('\\n') \n",
    "print ('沿轴 0 的最大值索引：') \n",
    "maxindex = np.argmax(x, axis =  0)  \n",
    "print (maxindex) \n",
    "print ('\\n') \n",
    "print ('沿轴 1 的最大值索引：') \n",
    "maxindex = np.argmax(x, axis =  1)  \n",
    "print (maxindex) \n",
    "print ('\\n') \n",
    "print ('调用 argmin() 函数：') \n",
    "minindex = np.argmin(x)  \n",
    "print (minindex) \n",
    "print ('\\n') \n",
    "print ('展开数组中的最小值：') \n",
    "print (x.flatten()[minindex]) \n",
    "print ('\\n') \n",
    "print ('沿轴 0 的最小值索引：') \n",
    "minindex = np.argmin(x, axis =  0)  \n",
    "print (minindex) \n",
    "print ('\\n') \n",
    "print ('沿轴 1 的最小值索引：') \n",
    "minindex = np.argmin(x, axis =  1)  \n",
    "print (minindex)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "原始数组是：\n",
      "[[0 1 2]\n",
      " [3 4 5]\n",
      " [6 7 8]]\n",
      "大于 3 的元素的索引：\n",
      "(array([1, 1, 2, 2, 2], dtype=int64), array([1, 2, 0, 1, 2], dtype=int64))\n",
      "使用这些索引来获取满足条件的元素：\n",
      "[4 5 6 7 8]\n",
      "如果数字大于3输出该数字，如果小于3则输出3\n",
      "[[3 3 3]\n",
      " [3 4 5]\n",
      " [6 7 8]]\n"
     ]
    }
   ],
   "source": [
    "# numpy.where() 函数返回输入数组中满足给定条件的元素的索引\n",
    "\n",
    "x = np.arange(9).reshape(3,  3)  \n",
    "print ('原始数组是：')\n",
    "print (x)\n",
    "print ( '大于 3 的元素的索引：')\n",
    "y = np.where(x >  3)  \n",
    "print (y)\n",
    "print ('使用这些索引来获取满足条件的元素：')\n",
    "print (x[y])\n",
    "\n",
    "# np.where(x) 输出的是5个判断为真的数的坐标，第一个array是横坐标，第二个array是纵坐标\n",
    "\n",
    "y = np.where(x>3, x, 3)\n",
    "print('如果数字大于3输出该数字，如果小于3则输出3')\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "原始数组是：\n",
      "[[0. 1. 2.]\n",
      " [3. 4. 5.]\n",
      " [6. 7. 8.]]\n",
      "按元素的条件值：\n",
      "[[ True False  True]\n",
      " [False  True False]\n",
      " [ True False  True]]\n",
      "使用条件提取元素：\n",
      "[0. 2. 4. 6. 8.]\n"
     ]
    }
   ],
   "source": [
    "# numpy.extract() 函数根据某个条件从数组中抽取元素，返回满条件的元素。\n",
    "\n",
    "x = np.arange(9.).reshape(3,  3)  \n",
    "print ('原始数组是：')\n",
    "print (x)\n",
    "# 定义条件, 选择偶数元素\n",
    "condition = np.mod(x,2)  ==  0  \n",
    "print ('按元素的条件值：')\n",
    "print (condition)\n",
    "print ('使用条件提取元素：')\n",
    "print (np.extract(condition, x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 数组运算\n",
    "\n",
    "- 求和运算\n",
    "- 求极值运算\n",
    "- 求均值\n",
    "- 求方差和标准差"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([10.26400127,  9.16671573,  8.39926713, 10.37403751, 11.87001419])"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 求5个股票收益率在N天中的和\n",
    "stock_return.sum(axis = 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.99782003, 0.86303888, 0.830863  , 0.99724603, 0.92626506])"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 求5个股票收益率在N天中的最大收益\n",
    "stock_return.max(axis = 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.99782003, 0.91972954, 0.65945356, 0.6173478 , 0.83526649,\n",
       "       0.59777641, 0.99724603, 0.68908272, 0.73225915, 0.73732918,\n",
       "       0.89416605, 0.86303888, 0.71402699, 0.98903386, 0.88161355,\n",
       "       0.82696571, 0.80861432, 0.84794746, 0.64734693, 0.96265043])"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 求N天中每天最大收益股票的收益值\n",
    "stock_return.max(axis = 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.51320006, 0.45833579, 0.41996336, 0.51870188, 0.59350071])"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 求5个股票收益率在N天中的平均收益\n",
    "stock_return.mean(axis = 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "方差\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([0.06111953, 0.05729788, 0.06141346, 0.10077193, 0.06787449])"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 求5个股票收益率在N天中的方差\n",
    "print('方差')\n",
    "stock_return.var(axis = 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "标准差\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([0.24722365, 0.23936975, 0.24781739, 0.31744595, 0.26052733])"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 求5个股票收益率在N天中的标准差\n",
    "print('标准差')\n",
    "stock_return.std(axis = 0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 矩阵操作\n",
    "\n",
    "- 矩阵的对角线，行列式\n",
    "- 矩阵相乘，矩阵的逆和特征值分解"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "协方差矩阵\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[ 1.        ,  0.71169998,  0.46246506,  0.05583479, -0.01801459],\n",
       "       [ 0.71169998,  1.        ,  0.23041479,  0.10558956, -0.11337707],\n",
       "       [ 0.46246506,  0.23041479,  1.        ,  0.28671801, -0.39583237],\n",
       "       [ 0.05583479,  0.10558956,  0.28671801,  1.        , -0.51279261],\n",
       "       [-0.01801459, -0.11337707, -0.39583237, -0.51279261,  1.        ]])"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 求5个股票收益率在N天中的协方差矩阵\n",
    "print('协方差矩阵')\n",
    "np.corrcoef(stock_return.T)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1., 1., 1., 1., 1.])"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 对角线元素\n",
    "stock_corr = np.corrcoef(stock_return.T)\n",
    "np.diag(stock_corr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.20961763497989772"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算行列式\n",
    "import numpy.linalg as la\n",
    "stock_corr = np.corrcoef(stock_return.T)\n",
    "la.det(stock_corr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([2.17724511, 1.45884805, 0.20161953, 0.47914389, 0.68314342]),\n",
       " array([[-0.5061784 , -0.47674729, -0.70321198, -0.14260177,  0.04065837],\n",
       "        [-0.47258042, -0.43047502,  0.55522597,  0.24381764, -0.47290177],\n",
       "        [-0.50395136,  0.10484992,  0.36892797, -0.16545308,  0.75601386],\n",
       "        [-0.35314262,  0.52323824,  0.00202759, -0.63339142, -0.44757484],\n",
       "        [ 0.37652954, -0.55011955,  0.2471944 , -0.70118349,  0.05320361]]))"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 特征值分解 singular value decomposition\n",
    "import numpy.linalg as la\n",
    "stock_corr = np.corrcoef(stock_return.T)\n",
    "la.eig(stock_corr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "jupyter": {
     "outputs_hidden": true
    }
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
